"""
调度相关API
"""

from flask import request, jsonify
from flask_jwt_extended import jwt_required, get_jwt_identity
from app import db
from app.models import Appointment, Resource, SchedulingResult, User
from app.api import api_bp
from app.scheduling import NSGA2Scheduler, WOAScheduler, DQNScheduler, HybridScheduler

@api_bp.route('/scheduling/optimize', methods=['POST'])
@jwt_required()
def optimize_schedule():
    """执行调度优化"""
    user_id = get_jwt_identity()
    user = User.query.get(user_id)
    
    # 权限检查
    if user.role not in ['admin', 'doctor']:
        return jsonify({'error': '无权限操作'}), 403
    
    data = request.get_json()
    algorithm = data.get('algorithm', 'hybrid')
    department_id = data.get('department_id')
    
    # 获取预约和资源数据
    appointments_query = Appointment.query.filter_by(status='pending')
    resources_query = Resource.query.filter_by(status='available')
    
    if department_id:
        appointments_query = appointments_query.filter_by(department_id=department_id)
        resources_query = resources_query.filter_by(department_id=department_id)
    
    appointments = appointments_query.all()
    resources = resources_query.all()
    
    if not appointments:
        return jsonify({'error': '没有待调度的预约'}), 400
    
    if not resources:
        return jsonify({'error': '没有可用资源'}), 400
    
    # 准备数据
    appointments_data = []
    for appointment in appointments:
        appointments_data.append({
            'id': appointment.id,
            'department_id': appointment.department_id,
            'preferred_time': appointment.scheduled_time,
            'duration': appointment.duration,
            'priority': appointment.priority
        })
    
    resources_data = []
    for resource in resources:
        resources_data.append({
            'id': resource.id,
            'name': resource.name,
            'resource_type': resource.resource_type,
            'department_id': resource.department_id,
            'status': resource.status
        })
    
    # 选择调度算法
    if algorithm == 'nsga2':
        scheduler = NSGA2Scheduler()
    elif algorithm == 'woa':
        scheduler = WOAScheduler()
    elif algorithm == 'dqn':
        scheduler = DQNScheduler()
    else:
        scheduler = HybridScheduler()
    
    # 执行调度
    result = scheduler.optimize(
        resources=resources_data,
        appointments=appointments_data,
        objectives=['resource_utilization', 'patient_wait_time', 'fairness', 'overtime_cost']
    )
    
    # 保存调度结果
    scheduling_result = SchedulingResult(
        algorithm_used=algorithm,
        optimization_objectives=result['objectives'],
        resource_utilization=result['objectives'].get('resource_utilization', 0),
        patient_wait_time=result['objectives'].get('patient_wait_time', 0),
        fairness_score=result['objectives'].get('fairness', 0),
        execution_time=result.get('execution_time', 0)
    )
    
    db.session.add(scheduling_result)
    db.session.commit()
    
    return jsonify({
        'scheduling_id': scheduling_result.id,
        'algorithm': algorithm,
        'objectives': result['objectives'],
        'solution': result['solution'],
        'message': '调度完成'
    })

@api_bp.route('/scheduling/history', methods=['GET'])
@jwt_required()
def get_scheduling_history():
    """获取调度历史"""
    user_id = get_jwt_identity()
    user = User.query.get(user_id)
    
    # 权限检查
    if user.role not in ['admin', 'doctor']:
        return jsonify({'error': '无权限访问'}), 403
    
    # 获取调度历史
    results = SchedulingResult.query.order_by(SchedulingResult.created_at.desc()).limit(50).all()
    
    history = []
    for result in results:
        history.append({
            'id': result.id,
            'algorithm_used': result.algorithm_used,
            'resource_utilization': result.resource_utilization,
            'patient_wait_time': result.patient_wait_time,
            'fairness_score': result.fairness_score,
            'execution_time': result.execution_time,
            'created_at': result.created_at.isoformat()
        })
    
    return jsonify(history)

@api_bp.route('/scheduling/real-time', methods=['POST'])
@jwt_required()
def real_time_scheduling():
    """实时调度"""
    data = request.get_json()
    appointment_id = data.get('appointment_id')
    
    if not appointment_id:
        return jsonify({'error': '缺少预约ID'}), 400
    
    appointment = Appointment.query.get(appointment_id)
    if not appointment:
        return jsonify({'error': '预约不存在'}), 404
    
    # 获取可用资源
    resources = Resource.query.filter_by(
        department_id=appointment.department_id,
        status='available'
    ).all()
    
    if not resources:
        return jsonify({'error': '没有可用资源'}), 400
    
    # 使用DQN进行实时调度
    scheduler = DQNScheduler()
    
    resources_data = [{
        'id': r.id,
        'name': r.name,
        'resource_type': r.resource_type,
        'department_id': r.department_id,
        'status': r.status
    } for r in resources]
    
    appointments_data = [{
        'id': appointment.id,
        'department_id': appointment.department_id,
        'preferred_time': appointment.scheduled_time,
        'duration': appointment.duration,
        'priority': appointment.priority
    }]
    
    result = scheduler.optimize(
        resources=resources_data,
        appointments=appointments_data,
        objectives=['resource_utilization', 'patient_wait_time']
    )
    
    return jsonify({
        'appointment_id': appointment_id,
        'result': result,
        'message': '实时调度完成'
    })

@api_bp.route('/scheduling/conflicts', methods=['GET'])
@jwt_required()
def get_scheduling_conflicts():
    """获取调度冲突"""
    user_id = get_jwt_identity()
    user = User.query.get(user_id)
    
    # 权限检查
    if user.role not in ['admin', 'doctor']:
        return jsonify({'error': '无权限访问'}), 403
    
    # 查询时间冲突
    conflicts = db.session.query(
        ResourceSchedule.resource_id,
        Resource.name.label('resource_name'),
        db.func.count(ResourceSchedule.id).label('conflict_count')
    ).join(Resource).filter(
        ResourceSchedule.status == 'occupied'
    ).group_by(
        ResourceSchedule.resource_id, Resource.name
    ).having(
        db.func.count(ResourceSchedule.id) > 1
    ).all()
    
    conflict_list = []
    for resource_id, resource_name, conflict_count in conflicts:
        conflict_list.append({
            'resource_id': resource_id,
            'resource_name': resource_name,
            'conflict_count': conflict_count
        })
    
    return jsonify(conflict_list)

@api_bp.route('/scheduling/performance', methods=['GET'])
@jwt_required()
def get_scheduling_performance():
    """获取调度性能指标"""
    user_id = get_jwt_identity()
    user = User.query.get(user_id)
    
    # 权限检查
    if user.role not in ['admin', 'doctor']:
        return jsonify({'error': '无权限访问'}), 403
    
    # 获取最近30天的性能数据
    from datetime import datetime, timedelta
    end_date = datetime.now()
    start_date = end_date - timedelta(days=30)
    
    results = SchedulingResult.query.filter(
        SchedulingResult.created_at >= start_date,
        SchedulingResult.created_at <= end_date
    ).all()
    
    if not results:
        return jsonify({'error': '没有性能数据'}), 404
    
    # 计算平均性能指标
    avg_utilization = sum(r.resource_utilization for r in results) / len(results)
    avg_wait_time = sum(r.patient_wait_time for r in results) / len(results)
    avg_fairness = sum(r.fairness_score for r in results) / len(results)
    avg_execution_time = sum(r.execution_time for r in results) / len(results)
    
    # 按算法分组统计
    algorithm_stats = {}
    for result in results:
        algorithm = result.algorithm_used
        if algorithm not in algorithm_stats:
            algorithm_stats[algorithm] = {
                'count': 0,
                'avg_utilization': 0,
                'avg_wait_time': 0,
                'avg_fairness': 0,
                'avg_execution_time': 0
            }
        
        algorithm_stats[algorithm]['count'] += 1
        algorithm_stats[algorithm]['avg_utilization'] += result.resource_utilization
        algorithm_stats[algorithm]['avg_wait_time'] += result.patient_wait_time
        algorithm_stats[algorithm]['avg_fairness'] += result.fairness_score
        algorithm_stats[algorithm]['avg_execution_time'] += result.execution_time
    
    # 计算平均值
    for algorithm in algorithm_stats:
        count = algorithm_stats[algorithm]['count']
        algorithm_stats[algorithm]['avg_utilization'] /= count
        algorithm_stats[algorithm]['avg_wait_time'] /= count
        algorithm_stats[algorithm]['avg_fairness'] /= count
        algorithm_stats[algorithm]['avg_execution_time'] /= count
    
    return jsonify({
        'overall_performance': {
            'avg_resource_utilization': round(avg_utilization, 2),
            'avg_patient_wait_time': round(avg_wait_time, 2),
            'avg_fairness_score': round(avg_fairness, 2),
            'avg_execution_time': round(avg_execution_time, 2)
        },
        'algorithm_performance': algorithm_stats
    })
